package at.socialconference.web.client.ui;

import java.util.List;

import at.socialconference.inter.connection.protocol.SocketProtocol;
import at.socialconference.inter.model.Conference;
import at.socialconference.inter.model.User;
import at.socialconference.web.client.SCwebService;
import at.socialconference.web.client.controller.ViewController;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;


//if you are authenticated as a conference, youre tweets will always be shown, and you
//will never be in the isFollowed list, and of course you cant follow yourself!
/**
 * class that provides the Twitter functionality for this app
 */
public class FriendsTwitter extends Composite {

	private AbsolutePanel backPanel;
	private static List<Conference> confs;
	
	final TextArea followedTweetsArea = new TextArea();
	final TextArea conferenceTweetsArea = new TextArea();
	
	// braucht innere klasse fuer alle callbackMethoden...
	private class AsyncCallbackGetAuthURL implements AsyncCallback<String> {
		private HTML lbl;

		public AsyncCallbackGetAuthURL(HTML lbl) {
			// Window.alert("getAuthUrl constructor");
			this.lbl = lbl;
		}

		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Error GetAuthUrl OnFailure: " + caught.getMessage());
			System.out.println("Errrrrrrrrrrrrrrrrrrrrror----GetAuthUrl");
		}

		@Override
		public void onSuccess(String result) {
			if(result.contains("stress nit")){
				Window.alert("Please wait for answer or use the shown URL.\n" +
						" If no URL appears you have to login again!");
				return;
			}
			lbl.setHTML("<a href="+result+" target=_blank>"+result+"</a><br>");
			//Window.alert(result);
		}
	}
	
	//quick n dirty
	public class AsyncCallbackGetClientUser2 implements AsyncCallback<User> {
		public void onFailure(Throwable caught) {
			Window.alert("error #312");
		}

		public void onSuccess(User result) {

			if (result!=null) {
				ViewController.getInstance().setUser(result);
				drawTwitterWindowVeryFastQuicknDirty(result);
			}
			else 
				drawTwitterWindowVeryFastQuicknDirty(ViewController.getInstance().getClientUser());
		}
	}

	private class AsyncCallbackFollow implements AsyncCallback<Integer> {
		public AsyncCallbackFollow() {
			// Window.alert("follow constructor");
		}

		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Unable to access you Twitter account, did you already give access to the app?");
			System.out.println("Errrrrrrrrrrrrrrrrrrrrror------Follow\n"+caught.getMessage());
		}

		@Override
		public void onSuccess(Integer result) {
			switch (result) {
			case 1:
				Window.alert("Nice! You are following now the selected Conference on Twitter");
				;
				break;
			case -1:
				Window.alert("Error, please contact your friendly sysadmin!");
				;
				break;
			case -2:
				Window.alert("Access Denied. You probably revoked access for this program in your Twitter Account.\n" +
				"Please reload this page and repeat the authorization process.");
				User clientUser = ViewController.getInstance().getClientUser();
				clientUser.setTw_access_secret(null);
				clientUser.setTw_access_token(null);
				SCwebService.Util.getInstance().updateObject(clientUser, new AsyncCallbackUpdateObject());
				break;
			case 2:
				Window.alert("Nice, you are already following the selected Conference");
				;
				break;
			default:
				Window.alert("Something very weird just happend! Contact Sysadmin");
				break;
			}
		}
	}
	
	private class AsyncCallbackUnFollow implements AsyncCallback<Integer> {
		public AsyncCallbackUnFollow() {
			// Window.alert("follow constructor");
		}

		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Unable to access you Twitter account, did you already give access to the app?" );
			System.out.println("Errrrrrrrrrrrrrrrrrrrrror------unFollow\n"+ caught.getMessage());
		}

		@Override
		public void onSuccess(Integer result) {
			switch (result) {
			case 1:
				Window.alert("Success!\n But what a pity, you are not following the selectect Conference anymore");
				;
				break;
			case -1:
				Window.alert("Error, please contact your friendly sysadmin!");
				;
				break;
			case -2:
				Window.alert("Access Denied. You probably revoked access for this program in your twitter account, please reload this page and repeat the authorization process.");
				User clientUser = ViewController.getInstance().getClientUser();
				clientUser.setTw_access_secret(null);
				clientUser.setTw_access_token(null);
				SCwebService.Util.getInstance().updateObject(clientUser, new AsyncCallbackUpdateObject());
				break;
			case 2:
				Window.alert("It seems you never followed the selected conference");
				;
				break;
			default:
				Window.alert("Something very weird just happend! Contact Sysadmin");
				break;
			}
		}
	}

	private class AsyncCallbackCreateAccToken implements AsyncCallback<Integer> {
		public AsyncCallbackCreateAccToken() {
			// Window.alert("creatAccToken, constructor");
		}

		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Error createAccToken OnFailure: " + caught.getMessage());
			System.out.println("Errrrrrrrrrrrrrrrrrrrrror------Follow");
		}

		@Override
		public void onSuccess(Integer result) {
			switch (result) {
			case 1:
				//Window.alert("You are logged in now!");
				//TODO: Page neu laden und global boolean einf�hren der mit clientUser.hasSecrets()==false
				//abgefragt wird, damit wenn das Token kommt die URL und lets go button verschwinden k�nnen.
				;
				SCwebService.Util.getInstance().getTimelines(new AsyncCallbackGetTimelines(conferenceTweetsArea));
				SCwebService.Util.getInstance().getFriends(new AsyncCallbackGetFriends(followedTweetsArea));
				
				break;
			case -1:
				Window.alert("Error 401, not possible to get token");
				;
				break;
			case -2:
				Window.alert("Error,\n your PIN might not be correct\n" +
						" please try again with correct PIN");
				break;
			case -3:
				Window.alert("Error, your PIN might not be correct, please press above button for a new URL");
				;
				break;
			default:
				Window.alert("Something weeeeeeird just happend!");
				break;
			}
		}
	}

	private class AsyncCallbackGetTimelines implements AsyncCallback<String> {
		private TextArea txtArea;

		public AsyncCallbackGetTimelines(TextArea txtArea) {
			// Window.alert("gettimlines constructor");
			this.txtArea = txtArea;
		}

		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Unable to access you Twitter account, did you already give access to the app?");
			System.out.println("Errrrrrrrrrrrrrrrrrrrrror----GetTimelines\n" + caught.getMessage());
		}

		@Override
		public void onSuccess(String result) {
			if(result.equals("")){
				Window.alert("You probably do not follow any of our conferences, you can change that right now!");
			}else if(result.equals("401")){
				Window.alert("Access Denied. You probably revoked access for this program in your Twitter Account.\n" );
				User clientUser = ViewController.getInstance().getClientUser();
				clientUser.setTw_access_secret(null);
				clientUser.setTw_access_token(null);
				SCwebService.Util.getInstance().updateObject(clientUser, new AsyncCallbackUpdateObject());		
				return;
			}
			txtArea.setText(result);
			// Window.alert(result);
		}
	}

	private class AsyncCallbackGetConferences implements AsyncCallback<List<Conference>> {
		private ListBox lstBx;

		public AsyncCallbackGetConferences(ListBox lstBx) {
			this.lstBx = lstBx;
		}

		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Error getConfs OnFailure: " + caught.getMessage());
			System.out.println("Errrrrrrrrrrrrrrrrrrrrror----GetConferences");
		}

		@Override
		public void onSuccess(List<Conference> confs) {
			FriendsTwitter.confs=confs;
			for (int i = 0; i < confs.size(); i++) {
				lstBx.addItem(confs.get(i).getName());
			}

		}
	}

	private class AsyncCallbackGetFriends implements AsyncCallback<String> {
		private TextArea txtArea;

		public AsyncCallbackGetFriends(TextArea txtArea) {
			this.txtArea = txtArea;
		}

		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Error getFriends OnFailure: " + caught.getMessage());
			System.out.println("Errrrrrrrrrrrrrrrrrrrrror----getFriends");
		}

		@SuppressWarnings("unused")
		@Override
		public void onSuccess(String result) {
			if (result.equals("Error:401")){
				Window.alert("Unable to access you Twitter account, did you already give access to the app?");
				return;
			}
			if(result==null){
				txtArea.setText("you are not following any of our Conferences...");
				return;
			}
			txtArea.setText(result);
			// Window.alert(result);
		}
	}
	
	private class AsyncCallbackUpdateObject implements AsyncCallback<Integer> {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert("Could not reach server");
		}

		@Override
		public void onSuccess(Integer result) {
			switch (result) {
			case SocketProtocol.OK:
				//DO NOTHING
				break;
			case SocketProtocol.RESP_WRONG_OBJECT:
				Window.alert("Error: UpdateObject: wrong object");
				;
				break;
			case -1:
				Window.alert("Error: UpdateObject: internal server error");
				;
				break;
			default:
				Window.alert("Something very weird just happend! Contact Sysadmin");
				break;
			}
		}
	}
	
	public FriendsTwitter() {
		SCwebService.Util.getInstance().getClientUser(new AsyncCallbackGetClientUser2());
		backPanel = new AbsolutePanel();
		backPanel.setSize("1100px", "1000px");
		initWidget(backPanel);
	}
	
	private void drawTwitterWindowVeryFastQuicknDirty(User clientUser) {
		
		final HTML urlLbl;
		Label follConf;
		
		//checking if we have access to this users twitter account (better: if this user gave us access to any twitter account)
		//Window.alert("token " + clientUser.getTw_access_secret() + " " + clientUser.getTw_access_token());
		if (clientUser.hasSecrets()==false) {

			Label label = new Label(
					"To be able to make you follow the above Conferences you need to allow this app to access your twitter account. To do this click on the above Button. It will give you an URL for a Webpage on which you have to enter your credentials. After that a PIN Number will appear. Please copy that code and enter it in the appropriate field.");
			backPanel.add(label, 0, 0);
			label.setSize("471px", "98px");

			urlLbl = new HTML("Please press above Button to see URL!");
			urlLbl.setSize("493px", "45px");
			backPanel.add(urlLbl, 10, 136);
			
			Button urlBttn = new Button("Show me the URL!");
			backPanel.add(urlBttn, 10, 102);
			urlBttn.setSize("155px", "28px");

			urlBttn.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent Klikka) {
					SCwebService.Util.getInstance().getAuthURL(new AsyncCallbackGetAuthURL(urlLbl));
					// Window.alert("button gepresst!");
				};
			});

			Label label_1 = new Label("Please copy the given PIN number in here:");
			backPanel.add(label_1, 2, 187);

			final IntegerBox iB = new IntegerBox();
			backPanel.add(iB, 2, 211);
			iB.setSize("140px", "22px");

			final CheckBox permanentBox = new CheckBox(
					"Check this box if you do not want to do this procedure again. You can always deny this app access in your twitter account.");
			permanentBox.setValue(true);
			backPanel.add(permanentBox, 1, 245);
			permanentBox.setSize("448px", "39px");

			Button getAuthTokenBttn = new Button("Lets go!");
			backPanel.add(getAuthTokenBttn, 154, 211);
			getAuthTokenBttn.setSize("100px", "28px");

			getAuthTokenBttn.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent Klikka) {
					if(iB.getText().length()!=7){
						Window.alert("The PIN you entered is not exactly 7 characters long, as it should be!");
					}else{
						SCwebService.Util.getInstance().createAccToken(iB.getText(),permanentBox.getValue(), new AsyncCallbackCreateAccToken());
					}
				};
			});

		} else {
			Label label = new Label(
					"You already gave this app access to your twitter account. Thank you. You can always undo this in your twitter account.");
			backPanel.add(label, 0, 171);
			label.setSize("471px", "98px");
		}

		follConf = new Label("At the moment you can follow the following conferences on Twitter.\n" + "Please choose which you want to follow:");
		follConf.setSize("470px", "45px");

		backPanel.add(follConf, 0, 354);

		final ListBox conferencesLstBx = new ListBox();
		backPanel.add(conferencesLstBx, 0, 405);
		conferencesLstBx.setSize("314px", "113px");
		conferencesLstBx.setVisibleItemCount(5);
		
		
		SCwebService.Util.getInstance().getConferences(new AsyncCallbackGetConferences(conferencesLstBx));

		Button followBttn = new Button("Follow");
		backPanel.add(followBttn, 0, 524);
		followBttn.setSize("100px", "28px");

		followBttn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent Klikka) {
				int confID=conferencesLstBx.getSelectedIndex();
				if(confID==-1){
					Window.alert("Please select a Conference from the above list first");
				}else{
					SCwebService.Util.getInstance().follow(confs.get(confID).getId(), new AsyncCallbackFollow());
				}
				// Window.alert("follow gedruckt!");
			};

		});
		
		Button unFollowBttn = new Button("Unfollow");
		backPanel.add(unFollowBttn, 201, 524);
		unFollowBttn.setSize("113px", "28px");
		
		unFollowBttn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent Klikka) {
				int confID=conferencesLstBx.getSelectedIndex();
				if(confID==-1){
					Window.alert("Please select a Conference from the above list first");
				}else{
					//Window.alert("unfollow "+confs.get(confID).getId());
					SCwebService.Util.getInstance().unFollow(confs.get(confID).getId(), new AsyncCallbackUnFollow());
				}
			};

		});

		Label label_2 = new Label("At the moment you are following these conferences:");
		backPanel.add(label_2, 505, 1);

		
		followedTweetsArea.setText("Press button to show content...");
		followedTweetsArea.setReadOnly(true);
		backPanel.add(followedTweetsArea, 505, 25);
		followedTweetsArea.setSize("314px", "117px");
		
		Button f5ConfsBttn = new Button("Follow them!");
		f5ConfsBttn.setText("Refresh List");
		backPanel.add(f5ConfsBttn, 505, 156);
		f5ConfsBttn.setSize("100px", "28px");

		f5ConfsBttn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent Klikka) {
				SCwebService.Util.getInstance().getFriends(new AsyncCallbackGetFriends(followedTweetsArea));
			};

		});

		Label label_3 = new Label("These are the last tweets coming from the conferences:");
		backPanel.add(label_3, 505, 201);
		label_3.setSize("305px", "45px");

		
		conferenceTweetsArea.setText("Press button to show content...");
		conferenceTweetsArea.setReadOnly(true);
		backPanel.add(conferenceTweetsArea, 505, 252);
		conferenceTweetsArea.setSize("314px", "416px");

		Button refreshBttn = new Button("Refresh Tweets");
		backPanel.add(refreshBttn, 505, 688);
		refreshBttn.setSize("187px", "28px");

		refreshBttn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent Klikka) {
				SCwebService.Util.getInstance().getTimelines(new AsyncCallbackGetTimelines(conferenceTweetsArea));
				// Window.alert("howz fresh, ha?");
			};
		});


	}
}
